require "std"

local focus=5
local yaw=1
local pitch=1
local distance=25
local cos_pitch, sin_pitch=math.cos(pitch), math.sin(pitch)
local cos_yaw, sin_yaw=math.cos(yaw), math.sin(yaw)
local translateX, translateY, scale=0,0,1
view={}


function view.transform(ox,oy,s)
  translateX,translateY,scale=ox,oy,s
end


function view.raise(delta)
  pitch=math.bound(pitch-delta,0.1,1.5)
  cos_pitch,sin_pitch=math.cos(pitch), math.sin(pitch)
  eye=view.eye()
end

function view.turn(delta)
  yaw=yaw-delta
  cos_yaw,sin_yaw=math.cos(yaw), math.sin(yaw)
  eye=view.eye()
end

function view.move(delta)
  distance=math.bound(distance*delta,6,100)
  eye=view.eye()
end

function view.project(v)
  local x,y,z=unpack(v)
  x,y= cos_yaw*x-sin_yaw*y, sin_yaw*x+cos_yaw*y
  y,z = cos_pitch*y-sin_pitch*z, sin_pitch*y+cos_pitch*z
  z = distance-z
  local p=focus/z
  if p<0 then p=1000 end
  return x*p*scale+translateX, y*p*scale+translateY, distance-z, p*scale
end

function view.eye()
  local x,y,z=0,0,distance
  y,z = cos_pitch*y+sin_pitch*z, -sin_pitch*y+cos_pitch*z --y equals 0, isn't it?
  x,y = cos_yaw*x+sin_yaw*y, -sin_yaw*x+cos_yaw*y
  return {x,y,z}
end
